// hwinxml.h

#pragma once
#ifndef __HWINXML_H__
#define __HWINXML_H__

#include "hwindef.h"
#include "hwincom.h"
#include "hwinexception.h"
#include "hwinvariant.h"
#include "hwinobj.h"

#include <msxml6.h>


namespace harlinn
{
    namespace windows
    {
        namespace xml
        {
            namespace dom
            {

                class Implementation : public Dispatch
                {
                public:
                    typedef Dispatch Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Implementation, Dispatch,IXMLDOMImplementation,IDispatch)

                    bool HasFeature( BSTR feature, BSTR version)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->hasFeature( feature, version, &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }
        
                };

                enum class NodeType
                {
                    Invalid = NODE_INVALID,
                    Element = NODE_ELEMENT,
                    Attribute = NODE_ATTRIBUTE,
                    Text = NODE_TEXT,
                    CDataSection = NODE_CDATA_SECTION,
                    EntityReference = NODE_ENTITY_REFERENCE,
                    Entity = NODE_ENTITY,
                    ProcessingInstruction = NODE_PROCESSING_INSTRUCTION,
                    Comment = NODE_COMMENT,
                    Document = NODE_DOCUMENT,
                    DocumentType = NODE_DOCUMENT_TYPE,
                    DocumentFragment = NODE_DOCUMENT_FRAGMENT,
                    Notation = NODE_NOTATION
                };

                typedef SysString XmlString;

                class NodeList;
                class NamedNodeMap;
                class Document;

                class Node : public Dispatch
                {
                public:
                    typedef Dispatch Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Node, Dispatch,IXMLDOMNode,IDispatch)


                    XmlString NodeName( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_nodeName(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    Variant NodeValue( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        Variant result;
                        auto hr = pInterface->get_nodeValue(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                    Node& SetNodeValue(const VARIANT& value)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_nodeValue(value);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    NodeType NodeType( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        DOMNodeType result;
                        auto hr = pInterface->get_nodeType(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return harlinn::windows::xml::dom::NodeType(result);
                    }
        
                    Node ParentNode( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->get_parentNode(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    NodeList ChildNodes( ) const;
        
                    Node FirstChild( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->get_firstChild(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Node LastChild( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->get_lastChild(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Node PreviousSibling( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->get_previousSibling(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Node NextSibling( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->get_nextSibling(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    NamedNodeMap Attributes() const;
        
                    Node InsertBefore( IXMLDOMNode *newChild,const VARIANT& refChild)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->insertBefore( newChild, refChild,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Node ReplaceChild( IXMLDOMNode *newChild,IXMLDOMNode *oldChild)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->replaceChild( newChild, oldChild,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Node RemoveChild( IXMLDOMNode *childNode )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->removeChild( childNode,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Node AppendChild( IXMLDOMNode *newChild )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->appendChild( newChild,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }

                    bool HasChildNodes( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->hasChildNodes( &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }
        
                    Document OwnerDocument( ) const;
        
                    Node CloneNode( bool deep = true)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->cloneNode( deep?VARIANT_TRUE:VARIANT_FALSE,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    XmlString NodeTypeString( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_nodeTypeString(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    XmlString Text( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_text(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    Node& SetText( BSTR text)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_text(text);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    bool Specified( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->get_specified( &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }
        
                    Node Definition( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->get_definition( &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Variant NodeTypedValue( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        Variant result;
                        auto hr = pInterface->get_nodeTypedValue( &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                    Node& SetNodeTypedValue( const VARIANT& typedValue )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_nodeTypedValue( typedValue );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    Variant DataType( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        Variant result;
                        auto hr = pInterface->get_dataType( &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }

                    Node& SetDataType( BSTR dataTypeName )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_dataType(dataTypeName);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    XmlString Xml( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_xml(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    XmlString TransformNode( IXMLDOMNode *stylesheet)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->transformNode(stylesheet, &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    NodeList SelectNodes( BSTR queryString ) const;

                    Node SelectSingleNode( BSTR queryString ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->selectSingleNode( queryString,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    bool Parsed( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->get_parsed( &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }
        
                    XmlString NamespaceURI( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_namespaceURI(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    XmlString Prefix( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_prefix(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    XmlString BaseName( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_baseName(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    const Node& TransformNodeToObject( IXMLDOMNode *stylesheet, IXMLDOMDocument* outputObject) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        Variant destination(outputObject);
                        auto hr = pInterface->transformNodeToObject( stylesheet, destination);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }

                    const Node& transformNodeToObject( IXMLDOMNode *stylesheet, IStream* outputObject) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        Variant destination(outputObject);
                        auto hr = pInterface->transformNodeToObject( stylesheet, destination);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }


                };

                class NodeList : public Dispatch
                {
                public:
                    typedef Dispatch Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(NodeList, Dispatch,IXMLDOMNodeList,IDispatch)

                    Node Item( long index )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->get_item(index,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    long Length( ) const
                    {
                        HWIN_TRACE();
                        if(unknown)
                        {
                            auto pInterface = GetInterface();
                            long result = 0;
                            auto hr = pInterface->get_length(&result);
                            if(FAILED(hr))
                            {
                                CheckHRESULT(hr);
                            }
                            return result;
                        }
                        return 0;
                    }
        
                    Node NextNode( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result = nullptr;
                        auto hr = pInterface->nextNode(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    NodeList& Reset( void )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->reset( );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    EnumUnknown NewEnum( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IUnknown *pUnknown = nullptr;
                        auto hr = pInterface->get__newEnum(&pUnknown);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        IEnumUnknown* pEnum = nullptr;

                        hr = pUnknown->QueryInterface<IEnumUnknown>(&pEnum);
                        pUnknown->Release();
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return EnumUnknown(pEnum);
                    }
        
                };

                inline NodeList Node::ChildNodes( ) const
                {
                    HWIN_TRACE();
                    auto pInterface = GetInterface();
                    IXMLDOMNodeList *result = nullptr;
                    auto hr = pInterface->get_childNodes(&result);
                    if(FAILED(hr))
                    {
                        CheckHRESULT(hr);
                    }
                    return NodeList(result);
                }


                inline NodeList Node::SelectNodes( BSTR queryString ) const
                {
                    HWIN_TRACE();
                    auto pInterface = GetInterface();
                    IXMLDOMNodeList *result;
                    auto hr = pInterface->selectNodes(queryString, &result);
                    if(FAILED(hr))
                    {
                        CheckHRESULT(hr);
                    }
                    return NodeList(result);
                }


                class NamedNodeMap : public Dispatch
                {
                public:
                    typedef Dispatch Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(NamedNodeMap, Dispatch,IXMLDOMNamedNodeMap,IDispatch)

                    Node NamedItem( BSTR name )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result = nullptr;
                        auto hr = pInterface->getNamedItem(name,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Node SetNamedItem( IXMLDOMNode *newItem)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result = nullptr;
                        auto hr = pInterface->setNamedItem(newItem,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Node RemoveNamedItem( BSTR name )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result = nullptr;
                        auto hr = pInterface->removeNamedItem(name,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    Node Item( long index )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result;
                        auto hr = pInterface->get_item(index,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    long Length( ) const
                    {
                        HWIN_TRACE();
                        if(unknown)
                        {
                            auto pInterface = GetInterface();
                            long result = 0;
                            auto hr = pInterface->get_length(&result);
                            if(FAILED(hr))
                            {
                                CheckHRESULT(hr);
                            }
                            return result;
                        }
                        return 0;
                    }
        
                    Node QualifiedItem( BSTR baseName,BSTR namespaceURI)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result = nullptr;
                        auto hr = pInterface->getQualifiedItem(baseName,namespaceURI,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }

                    Node RemoveQualifiedItem( BSTR baseName,BSTR namespaceURI)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result = nullptr;
                        auto hr = pInterface->removeQualifiedItem(baseName,namespaceURI,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }

                    Node NextNode( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result = nullptr;
                        auto hr = pInterface->nextNode(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    NamedNodeMap& Reset( void )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->reset( );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    EnumUnknown NewEnum( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IUnknown *pUnknown = nullptr;
                        auto hr = pInterface->get__newEnum(&pUnknown);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        IEnumUnknown* pEnum = nullptr;

                        hr = pUnknown->QueryInterface<IEnumUnknown>(&pEnum);
                        pUnknown->Release();
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return EnumUnknown(pEnum);
                    }
        
                };

                inline NamedNodeMap Node::Attributes() const
                {
                    HWIN_TRACE();
                    auto pInterface = GetInterface();
                    IXMLDOMNamedNodeMap *result = nullptr;
                    auto hr = pInterface->get_attributes(&result);
                    if(FAILED(hr))
                    {
                        CheckHRESULT(hr);
                    }
                    return NamedNodeMap(result);
                }


                class DocumentType : public Node
                {
                public:
                    typedef Node Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(DocumentType, Node,IXMLDOMDocumentType,IXMLDOMNode)

                    XmlString Name( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_name(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    NamedNodeMap Entities( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNamedNodeMap *result = nullptr;
                        auto hr = pInterface->get_entities(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return NamedNodeMap(result);
                    }
        
                    NamedNodeMap get_notations( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNamedNodeMap *result = nullptr;
                        auto hr = pInterface->get_notations(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return NamedNodeMap(result);
                    }
        
                };


                class Attribute : public Node
                {
                public:
                    typedef Node Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Attribute, Node,IXMLDOMAttribute,IXMLDOMNode)

                    XmlString Name( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_name(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    Variant Value( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        Variant result;
                        auto hr = pInterface->get_value( &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                    Attribute& SetValue( const VARIANT& attributeValue )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_value( attributeValue );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
                };


                class Element : public Node
                {
                public:
                    typedef Node Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Element, Node,IXMLDOMElement,IXMLDOMNode)

                    XmlString TagName( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_tagName(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    Variant Attribute(BSTR name)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        Variant result;
                        auto hr = pInterface->getAttribute(name, &result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                    Element& SetAttribute( BSTR name,VARIANT value)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->setAttribute( name, value );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    Element& RemoveAttribute(BSTR name)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->removeAttribute( name );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    harlinn::windows::xml::dom::Attribute AttributeNode(BSTR name)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMAttribute *result = nullptr;
                        auto hr = pInterface->getAttributeNode(name,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return harlinn::windows::xml::dom::Attribute(result);
                    }
        
                    harlinn::windows::xml::dom::Attribute SetAttributeNode( IXMLDOMAttribute *DOMAttribute )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMAttribute *result = nullptr;
                        auto hr = pInterface->setAttributeNode(DOMAttribute,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return harlinn::windows::xml::dom::Attribute(result);
                    }
        
                    harlinn::windows::xml::dom::Attribute RemoveAttributeNode( IXMLDOMAttribute *DOMAttribute )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMAttribute *result = nullptr;
                        auto hr = pInterface->removeAttributeNode(DOMAttribute,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return harlinn::windows::xml::dom::Attribute(result);
                    }

                    NodeList ElementsByTagName( BSTR tagName )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNodeList *result = nullptr;
                        auto hr = pInterface->getElementsByTagName(tagName,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return NodeList(result);
                    }
        
                    Element& Normalize( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->normalize( );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                };


                class DocumentFragment : public Node
                {
                public:
                    typedef Node Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(DocumentFragment, Node,IXMLDOMDocumentFragment,IXMLDOMNode)
                };

                class CharacterData : public Node
                {
                public:
                    typedef Node Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(CharacterData, Node,IXMLDOMCharacterData,IXMLDOMNode)

                    XmlString Data( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_data(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    CharacterData& SetData( BSTR data )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_data(data);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    long Length( long *dataLength )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        long result = 0;
                        auto hr = pInterface->get_length(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                    XmlString SubstringData( long offset,long count,BSTR *data)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->substringData(offset,count,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    CharacterData& AppendData( BSTR data )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->appendData(data);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
                    CharacterData& InsertData( long offset, BSTR data)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->insertData(offset, data);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    CharacterData& DeleteData( long offset,long count) 
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->deleteData(offset, count );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }

                    CharacterData& ReplaceData( long offset,long count, BSTR data)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->replaceData(offset, count, data);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                };


                class Text : public CharacterData
                {
                public:
                    typedef CharacterData Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Text, CharacterData,IXMLDOMText,IXMLDOMCharacterData)

                    Text splitText( long offset )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMText *result = nullptr;
                        auto hr = pInterface->splitText(offset,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Text(result);
                    }
                };

                class Comment : public CharacterData
                {
                public:
                    typedef CharacterData Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Comment, CharacterData,IXMLDOMComment,IXMLDOMCharacterData)

                };



                class CDATASection : public Text
                {

                public:
                    typedef Text Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(CDATASection,Text,IXMLDOMCDATASection ,IXMLDOMText)
                };


                class ProcessingInstruction : public Node
                {
                public:
                    typedef Node Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(ProcessingInstruction, Node,IXMLDOMProcessingInstruction,IXMLDOMNode)

                    XmlString Target( BSTR *name)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_target(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }

                    XmlString Data( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_data(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    ProcessingInstruction& SetData( BSTR data )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_data(data);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                };


                class EntityReference : public Node
                {
                public:
                    typedef Node Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(EntityReference, Node,IXMLDOMEntityReference,IXMLDOMNode)
                };


                class ParseError : public Dispatch
                {
                public:
                    typedef Dispatch Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(ParseError, Dispatch,IXMLDOMParseError,IDispatch)

                    long  ErrorCode( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        long result = 0;
                        auto hr = pInterface->get_errorCode(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                    XmlString Url( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_url(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    XmlString Reason( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_reason(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    XmlString SrcText( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_srcText(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    long Line( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        long result = 0;
                        auto hr = pInterface->get_line(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                    long LinePos( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        long result = 0;
                        auto hr = pInterface->get_linepos(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                    long FilePos()
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        long result = 0;
                        auto hr = pInterface->get_filepos(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                };


                class SchemaCollection : public Dispatch
                {
                public:
                    typedef Dispatch Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(SchemaCollection, Dispatch,IXMLDOMSchemaCollection,IDispatch)

                    SchemaCollection& Add( BSTR namespaceURI, const VARIANT& var)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->add(namespaceURI, var);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    Node SchemaNodeForNamespace( BSTR namespaceURI )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode* result = 0;
                        auto hr = pInterface->get(namespaceURI,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    SchemaCollection& Remove( BSTR namespaceURI)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->remove(namespaceURI);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    long Length( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        long result = 0;
                        auto hr = pInterface->get_length(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }

                    XmlString At( long index )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_namespaceURI(index,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    XmlString NamespaceURI( long index )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = 0;
                        auto hr = pInterface->get_namespaceURI(index,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    SchemaCollection& AddCollection( IXMLDOMSchemaCollection *otherCollection)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->addCollection(otherCollection);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    EnumUnknown NewEnum( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IUnknown *pUnknown = nullptr;
                        auto hr = pInterface->get__newEnum(&pUnknown);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        IEnumUnknown* pEnum = nullptr;

                        hr = pUnknown->QueryInterface<IEnumUnknown>(&pEnum);
                        pUnknown->Release();
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return EnumUnknown(pEnum);
                    }
        
                };




                class Document : public Node
                {
                public:
                    typedef Node Base;
                    HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Document, Node,IXMLDOMDocument3,IXMLDOMNode)


                    DocumentType Doctype( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMDocumentType *result = nullptr;
                        auto hr = pInterface->get_doctype(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return DocumentType(result);
                    }
        
                    Implementation Implementation( ) const
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMImplementation *result = nullptr;
                        auto hr = pInterface->get_implementation(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return harlinn::windows::xml::dom::Implementation(result);
                    }
        
                    Element DocumentElement( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMElement *result = nullptr;
                        auto hr = pInterface->get_documentElement(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Element(result);
                    }
        
                    Document& SetDocumentElement( IXMLDOMElement *DOMElement )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->putref_documentElement(DOMElement);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    Element CreateElement( BSTR tagName )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMElement *result = nullptr;
                        auto hr = pInterface->createElement(tagName,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Element(result);
                    }

                    DocumentFragment CreateDocumentFragment( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMDocumentFragment *result = nullptr;
                        auto hr = pInterface->createDocumentFragment(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return DocumentFragment(result);
                    }

                    harlinn::windows::xml::dom::Text CreateTextNode( BSTR data )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMText *result = nullptr;
                        auto hr = pInterface->createTextNode(data,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return harlinn::windows::xml::dom::Text(result);
                    }
        
                    Comment CreateComment( BSTR data )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMComment *result = nullptr;
                        auto hr = pInterface->createComment(data,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Comment(result);
                    }
        
                    CDATASection CreateCDATASection( BSTR data )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMCDATASection *result = nullptr;
                        auto hr = pInterface->createCDATASection(data,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return CDATASection(result);
                    }

                    ProcessingInstruction CreateProcessingInstruction( BSTR target,BSTR data )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMProcessingInstruction *result = nullptr;
                        auto hr = pInterface->createProcessingInstruction(target,data,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return ProcessingInstruction(result);
                    }

                    Attribute CreateAttribute( BSTR name)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMAttribute *result = nullptr;
                        auto hr = pInterface->createAttribute(name,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Attribute(result);
                    }
        
                    EntityReference CreateEntityReference( BSTR name )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMEntityReference *result = nullptr;
                        auto hr = pInterface->createEntityReference(name,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return EntityReference(result);
                    }
        
                    NodeList ElementsByTagName( BSTR tagName )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNodeList *result = nullptr;
                        auto hr = pInterface->getElementsByTagName(tagName,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return NodeList(result);
                    }

                    Node CreateNode( const VARIANT& Type,BSTR name,BSTR namespaceURI,IXMLDOMNode **node)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result = nullptr;
                        auto hr = pInterface->createNode(Type,name,namespaceURI,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }

                    Node NodeFromID( BSTR idString )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode *result = nullptr;
                        auto hr = pInterface->nodeFromID(idString,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }
        
                    bool Load(const VARIANT& xmlSource)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->load(xmlSource,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }
        
                    long ReadyState( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        long result = VARIANT_FALSE;
                        auto hr = pInterface->get_readyState(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
        
                    ParseError ParseError( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMParseError* result = nullptr;
                        auto hr = pInterface->get_parseError(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return harlinn::windows::xml::dom::ParseError(result);
                    }

                    XmlString Url( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        BSTR result = nullptr;
                        auto hr = pInterface->get_url(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return XmlString(result,true);
                    }
        
                    bool Async( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->get_async(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }

                    Document& SetAsync( bool isAsync = true)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_async(isAsync?VARIANT_TRUE:VARIANT_FALSE);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    Document& Abort( void)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->abort( );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    bool LoadXML( BSTR bstrXML )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->loadXML(bstrXML,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }

                    Document& Save( const VARIANT& destination )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->save( destination );
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }

                    Document& Save( const String& destination )
                    {
                        HWIN_TRACE();
                        Variant arg( destination );
                        Save(arg);
                        return *this;
                    }

                    Document& Save( IStream* destination )
                    {
                        HWIN_TRACE();
                        Variant arg( destination ); 
                        Save(arg);
                        return *this;
                    }


        
                    bool ValidateOnParse( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->get_validateOnParse(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }
        
                    Document& SetValidateOnParse( bool isValidating = true)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_validateOnParse(isValidating?VARIANT_TRUE:VARIANT_FALSE);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }

                    bool ResolveExternals( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->get_resolveExternals(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }

                    Document& SetResolveExternals( bool isResolving = true)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_resolveExternals(isResolving?VARIANT_TRUE:VARIANT_FALSE);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    bool PreserveWhiteSpace( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        VARIANT_BOOL result = VARIANT_FALSE;
                        auto hr = pInterface->get_preserveWhiteSpace(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result != VARIANT_FALSE;
                    }
        

                    Document& SetPreserveWhiteSpace( bool isPreserving = true)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->put_preserveWhiteSpace(isPreserving?VARIANT_TRUE:VARIANT_FALSE);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        
                        return *this;
                    }
        
                    /*
                    HRESULT STDMETHODCALLTYPE put_onreadystatechange( VARIANT readystatechangeSink);
        
                    HRESULT STDMETHODCALLTYPE put_ondataavailable( VARIANT ondataavailableSink);
        
                    HRESULT STDMETHODCALLTYPE put_ontransformnode( VARIANT ontransformnodeSink);
                    */

                    SchemaCollection Namespaces( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMSchemaCollection *result = nullptr;
                        auto hr = pInterface->get_namespaces(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return SchemaCollection(result);
                    }
        
                    /*
                    HRESULT STDMETHODCALLTYPE get_schemas(VARIANT *otherCollection);
        
                    HRESULT STDMETHODCALLTYPE putref_schemas( VARIANT otherCollection);
                    */

                    harlinn::windows::xml::dom::ParseError Validate( )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMParseError* result = nullptr;
                        auto hr = pInterface->validate(&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return harlinn::windows::xml::dom::ParseError(result);
                    }
        
                    Document& SetProperty( BSTR name, const VARIANT& value)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        auto hr = pInterface->setProperty(name,value);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return *this;
                    }
        
                    Variant GetProperty( BSTR name)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        Variant result;
                        auto hr = pInterface->getProperty(name,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return result;
                    }
                        
                    harlinn::windows::xml::dom::ParseError validateNode( IXMLDOMNode *node )
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMParseError* result = nullptr;
                        auto hr = pInterface->validateNode(node,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return harlinn::windows::xml::dom::ParseError(result);
                    }
        
                    Node ImportNode( IXMLDOMNode *node,bool deep = true)
                    {
                        HWIN_TRACE();
                        auto pInterface = GetInterface();
                        IXMLDOMNode* result;
                        auto hr = pInterface->importNode(node,deep?VARIANT_TRUE:VARIANT_FALSE,&result);
                        if(FAILED(hr))
                        {
                            CheckHRESULT(hr);
                        }
                        return Node(result);
                    }

                };



                inline Document Node::OwnerDocument( ) const
                {
                    HWIN_TRACE();
                    auto pInterface = GetInterface();
                    IXMLDOMDocument *pDocument = nullptr;
                    auto hr = pInterface->get_ownerDocument(&pDocument);
                    if(FAILED(hr))
                    {
                        CheckHRESULT(hr);
                    }
                    IXMLDOMDocument3* pDocument3 = nullptr;

                    hr = pDocument->QueryInterface<IXMLDOMDocument3>(&pDocument3);
                    pDocument->Release();
                    if(FAILED(hr))
                    {
                        CheckHRESULT(hr);
                    }

                    return Document(pDocument3);
                }





            }

            namespace sax
            {
            }
        };
    };
};

#endif //__HWINXML_H__